#include "Logger.h"
#include "Exception.h"
#include <cstdio>

NS_B2D_BEGIN

Logger::Logger(void)
{
	memset(mOutputs, 0, MAX_OUTPUTS * sizeof(mOutputs[0]));
}

Logger::~Logger(void)
{
}

void Logger::log(LogLevel level, const string& file, int line, const string& function, const char* msg, ...)
{
	char buffer[BUFFER_SIZE] = {0};
	va_list args;
	va_start(args, msg);
	vsnprintf(buffer, BUFFER_SIZE, msg, args);
	va_end(args);

	string msgStr(buffer);
	for(auto it : mOutputs)
	{
		if(it != nullptr) it->log(level, msgStr, file, line, function);
	}
}

void Logger::log0(LogLevel level, const string& file, int line, const string& function, const string& msg)
{
	for(auto it : mOutputs)
	{
		if(it != nullptr) it->log(level, msg, file, line, function);
	}
}

void Logger::registerOutput(ILoggerOutput& output)
{
	std::lock_guard<std::mutex> lock(mOutputMutex);
	for(auto& it : mOutputs)
	{
		if(it == nullptr)
		{
			it = &output;
			return;
		}
	}
	B2D_THROW(Exception::INTERNAL_ERROR_EXCEPTION,
		"Can't register more than "+std::to_string(MAX_OUTPUTS)+" logger outputs.");
}

void Logger::unregisterOutput(ILoggerOutput& output)
{
	std::lock_guard<std::mutex> lock(mOutputMutex);
	for(auto& it : mOutputs)
	{
		if(it == &output)
		{
			it = nullptr;
			return;
		}
	}
}

void Logger::unregisterAllOutputs(void)
{
	std::lock_guard<std::mutex> lock(mOutputMutex);
	for(auto& it : mOutputs)
		it = nullptr;
}

size_t Logger::getOutputCount(void) const
{
	size_t count = 0;
	std::lock_guard<std::mutex> lock(mOutputMutex);
	for(auto& it : mOutputs)
		if(it != nullptr) ++count;
	return count;
}

NS_B2D_END